package servlet;

import java.awt.event.ItemListener;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.persistence.EntityManager;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.apache.commons.lang.math.RandomUtils;
import org.hsqldb.server.Server;

import com.labmi.experiment.Category;
import com.labmi.experiment.ClothingItem;
import com.labmi.experiment.Color;
import com.labmi.experiment.Item;
import com.labmi.experiment.ItemStock;
import com.labmi.experiment.Size;
import com.labmi.experiment.dao.CategoryDAO;
import com.labmi.experiment.dao.ColorDAO;
import com.labmi.experiment.dao.EntityManagerSingleton;
import com.labmi.experiment.dao.GenericDao;
import com.labmi.experiment.dao.ItemDAO;
import com.labmi.experiment.dao.SizeDAO;

/**
 * Servlet implementation class StartupServlet
 */
public class StartupServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	private static final String DEFAULT_JPA_PERSISTENCE_UNIT = "test_shopping";
	
	
    /**
     * @see HttpServlet#HttpServlet()
     */
    public StartupServlet() {
        super();
        
        
    }

	/**
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		java.util.Map<Object,Object> map = new java.util.HashMap<Object,Object>();
		String persistenceName = getServletContext().getInitParameter("PERSISTENCE_UNIT_NAME");
		
		if(persistenceName == null || persistenceName.isEmpty() )
		{
			System.out.println("'PERSISTENCE_UNIT_NAME' inside web.xml is empty. Switching to default persistence unit: '" + DEFAULT_JPA_PERSISTENCE_UNIT + "'");
			persistenceName = DEFAULT_JPA_PERSISTENCE_UNIT;
			
			startHSQLDatabaseServer();
		}
		
		System.out.println("Using 'PERSISTENCE_UNIT_NAME': " + persistenceName);
		
		String appendModeAsString = getServletContext().getInitParameter("POPULATE_DATABASE_APPEND_ITEMS");
		
		Boolean appendMode = Boolean.parseBoolean(appendModeAsString);
		
		EntityManager em = EntityManagerSingleton.getInstance(persistenceName);
		
		populateDatabase(em, appendMode);
		
		
		
		//TODO populate database
//		em.getTransaction().begin();
//		// we'll put some codes here later
//		em.getTransaction().commit();
//		em.close();
//		factory.close();
	}

	/**
	 * @see Servlet#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	private void populateDatabase(EntityManager em, boolean appendMode)
	{
		if(appendMode)
		{
			System.out.println("Appending new fake elements inside database...");
			insertMockDataInsideDB(em);
			
		}
		else
		{
			GenericDao<Item, Serializable> dao = new ItemDAO();
			
			List<Item> allItems = dao.fetchAll(-1); //NO LIMIT FETCH
			if( allItems == null || allItems.isEmpty() )
			{
				insertMockDataInsideDB(em);
			}
			else
				System.out.println("Database already contains data! Skipping population... ");
		}
	
	}
	
	
	
	private void insertMockDataInsideDB(EntityManager em)
	{
		boolean skipCategoriesPopulation = true;
		
		
		List<Category> categories;
		CategoryDAO categoryDAO = new CategoryDAO();
		SizeDAO sizeDAO = new SizeDAO();
		ItemDAO itemDao = new ItemDAO();
		ColorDAO colorDao = new ColorDAO();
		
		
		try {
			categories = categoryDAO.fetchAll(-1);
			if(categories == null || categories.isEmpty())
				skipCategoriesPopulation = false; //Let db populating with categories
			
		} catch (Exception e) {
			System.err.println("Problem inserting mock data on startup");
			e.printStackTrace();
		}
		if(  ! skipCategoriesPopulation )
		{
			em.getTransaction().begin();
			
			Category manCategory  = new Category();
				manCategory.setId(1);
				manCategory.setName("Uomo");
			
			Category manClothing  = new Category();
				manClothing.setId(10);	
				manClothing.setName("Abbigliamento");
				manClothing.setParent(1);
				
			Category manAccessories  = new Category();
				manAccessories.setId(30);	
				manAccessories.setName("Accessori");
				manAccessories.setParent(1);
			
			Category womenAccessories  = new Category();
				womenAccessories.setId(40);	
				womenAccessories.setName("Accessori");
				womenAccessories.setParent(2);	
				
			Category manAccessories_bag  = new Category();
				manAccessories_bag.setId(31);	
				manAccessories_bag.setName("Borse");
				manAccessories_bag.setParent(30);	
				
				
				
			Category manAccessories_belt  = new Category();
				manAccessories_belt.setId(32);	
				manAccessories_belt.setName("Cinture");
				manAccessories_belt.setParent(30);	
				
				
			Category womenAccessories_bag  = new Category();
				womenAccessories_bag.setId(41);	
				womenAccessories_bag.setName("Borse");
				womenAccessories_bag.setParent(40);	
				
			Category womenAccessories_belt  = new Category();
				womenAccessories_belt.setId(42);	
				womenAccessories_belt.setName("Cinture");
				womenAccessories_belt.setParent(40);		
				
				
			Category womanCategory  = new Category();
				womanCategory.setId(2);
				womanCategory.setName("Donna");
			
			Category womanClothing  = new Category();
				womanClothing.setId(20);	
				womanClothing.setName("Abbigliamento");
				womanClothing.setParent(2);	
				
			
			
			Category man_clothing_pullover  = new Category();
				man_clothing_pullover.setId(100);	
				man_clothing_pullover.setName("Pullover");
				man_clothing_pullover.setParent( manClothing.getId() );
				System.out.println("ID Categoria \"man>clothing\" : " + manClothing.getId());
				
			Category woman_clothing_pullover  = new Category();
				woman_clothing_pullover.setId(200);	
				woman_clothing_pullover.setName("Pullover");
				woman_clothing_pullover.setParent( womanClothing.getId() );	
				System.out.println("ID Categoria \"woman>clothing\" : " + womanClothing.getId());
				
			Category man_clothing_pants  = new Category();
				man_clothing_pants.setId(111);	
				man_clothing_pants.setName("Pantaloni");
				man_clothing_pants.setParent( manClothing.getId() );
				System.out.println("ID Categoria \"man>clothing\" : " + manClothing.getId());
				
			Category woman_clothing_pants  = new Category();
				woman_clothing_pants.setId(222);	
				woman_clothing_pants.setName("Pantaloni");
				woman_clothing_pants.setParent( womanClothing.getId() );	
				System.out.println("ID Categoria \"woman>clothing\" : " + womanClothing.getId());
			
				em.persist(manCategory);
					em.persist(manClothing);
						em.persist(man_clothing_pullover);
						em.persist(man_clothing_pants);
					em.persist(manAccessories);
						em.persist(manAccessories_bag);
						em.persist(manAccessories_belt);
						
				em.persist(womanCategory);
					em.persist(womanClothing);
						em.persist(woman_clothing_pullover);
						em.persist(woman_clothing_pants);
					em.persist(womenAccessories);
						em.persist(womenAccessories_bag);
						em.persist(womenAccessories_belt);	
				
				
						
			em.getTransaction().commit();
			
			loadSizeInsideDB(em);
			
			loadColorInsideDB(em);
			
		}
 
		
		em.getTransaction().begin();
		
		
		Category manClothingPullover = categoryDAO.read(100);
		Category manClothingPants = categoryDAO.read(111);
		Category womanClothingPullover = categoryDAO.read(200);
		Category womanClothingPants = categoryDAO.read(222);
		
		
		String randomCode = UUID.randomUUID().toString();
		//MEN ITEMs
		ClothingItem man1 =  
			new ClothingItem("Pullover 1 (stock test)", "Pullover in lana, scollo a V", 	200, "css/images/items/man/abbigliamento/pullover1.jpg","MAN");
			man1.setCode(randomCode);
			man1.setBrand("Armani");
			man1.setCategory(manClothingPullover); //Man>ClothingPullover
//			man1.addSize(sizeDAO.getSizeByName("L"));
			
			man1.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("L"), colorDao.getColorByName("Black"), 3) );
			man1.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("XL"), colorDao.getColorByName("Black"), 3) );
			man1.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("L"), colorDao.getColorByName("Blue"), 1) );
			
		
		ClothingItem man2 =  
			new ClothingItem("Pullover 2", "Pullover in lana, scollo a V", 	170, "css/images/items/man/abbigliamento/pullover2.jpg", "MAN");
			randomCode = UUID.randomUUID().toString();
			man2.setCode(randomCode);
			man2.setBrand("D&G");
			man2.setCategory(manClothingPullover); //Man>ClothingPullover
				man2.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("XS"), colorDao.getColorByName("Black"), 3) );
				man2.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("S"), colorDao.getColorByName("Black"), 3) );
				man2.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("L"), colorDao.getColorByName("Blue"), 1) );
				man2.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("XL"), colorDao.getColorByName("Blue"), 1) );
		
		ClothingItem man4 = 
			new ClothingItem("Pantaloni 1", "Pantaloni tuta", 	150, "css/images/items/man/abbigliamento/pantaloni1.jpg","UOMO");
			randomCode = UUID.randomUUID().toString();
			man4.setCode(randomCode);
			man4.setBrand("Guess");
			man4.setCategory(manClothingPants); //Man>ClothingPullover
			man4.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("XS"), colorDao.getColorByName("Black"), 3) );
			man4.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("S"), colorDao.getColorByName("Black"), 3) );
		
		ClothingItem man5 = 
			new ClothingItem("Pantaloni 2", "Pantaloni in lana", 	70, "css/images/items/man/abbigliamento/pantaloni2.jpg",  "UOMO");
		randomCode = UUID.randomUUID().toString();
		man5.setCode(randomCode);
		man5.setBrand("Levis");
		man5.setCategory(manClothingPants); //Man>ClothingPullover
			man5.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("XL"), colorDao.getColorByName("Black"), 3) );
			man5.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("L"), colorDao.getColorByName("Black"), 3) );
		
		
		
		//WOMEN ITEMs
		ClothingItem women1 =  
			new ClothingItem("Felpa 1", "Felpa donna", 	200, "css/images/items/woman/abbigliamento/felpaW1.jpg",  "WOMAN");
		randomCode = UUID.randomUUID().toString();
		women1.setCode(randomCode);	
		women1.setBrand("Armani");
			women1.setCategory(womanClothingPullover); 
				women1.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("XL"), colorDao.getColorByName("Black"), 3) );
				women1.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("L"), colorDao.getColorByName("Black"), 3) );
		
		ClothingItem women2 =  
			new ClothingItem("Felpa 2", "Felpa donna", 	170, "css/images/items/woman/abbigliamento/felpaW2.jpg", "WOMAN");
		randomCode = UUID.randomUUID().toString();
		women2.setCode(randomCode);		
		women2.setBrand("Armani");
			women2.setCategory(womanClothingPullover);
			women2.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("XL"), colorDao.getColorByName("Blue"), 3) );
			women2.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("S"), colorDao.getColorByName("Black"), 2) );
		
		
		ClothingItem women4 = 
			new ClothingItem("Pantaloni 1", "Pantaloni donna", 	150, "css/images/items/woman/abbigliamento/pantaloniW1.jpg", "WOMAN");
		randomCode = UUID.randomUUID().toString();
		women4.setCode(randomCode);	
		women4.setBrand("Armani");
		women4.setCategory(womanClothingPants); 
			women4.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("XL"), colorDao.getColorByName("Blue"), 3) );
			women4.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("S"), colorDao.getColorByName("Black"), 2) );
		
		ClothingItem women5 = 
			new ClothingItem("Pantaloni 2", "Pantaloni donna", 	70, "css/images/items/woman/abbigliamento/pantaloniW2.jpg",  "WOMAN");
		randomCode = UUID.randomUUID().toString();
		women5.setCode(randomCode);	
		women5.setBrand("Armani");
		women5.setCategory(womanClothingPants); 
		women5.addItemStock( new ItemStock(randomCode, sizeDAO.getSizeByName("XL"), colorDao.getColorByName("Blue"), 3) );
		
		
		 
		
		
		
//		pullover_Man_Clothing.addItem(i1);
//		pullover_Man_Clothing.addItem(i2);
//		pullover_Man_Clothing.addItem(i3);
//		pullover_Man_Clothing.addItem(i4);
//		pullover_Man_Clothing.addItem(i5);
//		pullover_Man_Clothing.addItem(i6);
		
		

//		em.persist( pullover_Man_Clothing );
//		Item i7 = new ClothingItem("Camicia", "Lorem ipsum dolor sit amet", 		50, "css/images/big1.jpg",  "UOMO");
//		Item i8 = new ClothingItem("Camicia", "Lorem ipsum dolor sit amet", 		50, "css/images/big1.jpg", "XL", "UOMO");
//		Item i9 = new ClothingItem("Pantaloni", "Lorem ipsum dolor sit amet", 	200, "css/images/big1.jpg",  "UOMO");
//		Item i10 = new ClothingItem("Pantaloni", "Lorem ipsum dolor sit amet", 	200, "css/images/big1.jpg",  "UOMO");
//		Item i11 = new ClothingItem("Pantaloni", "Lorem ipsum dolor sit amet", 	200, "css/images/big1.jpg",  "UOMO");
//		Item i12 = new ClothingItem("Giacca", "Lorem ipsum dolor sit amet", 		100, "css/images/big1.jpg",  "UOMO");
		
//		List<Item> listOfItemForCategory = new ArrayList<Item>();
//		listOfItemForCategory.add(i1);
//		listOfItemForCategory.add(i2);
//		listOfItemForCategory.add(i3);
//		listOfItemForCategory.add(i4);
//		
//		clothingCategory.setItemList(listOfItemForCategory);
		
		
		
		
		
		em.persist(man1);
		em.persist(man2);
		em.persist(man4);
		em.persist(man5);
		
		em.persist(women1);
		em.persist(women2);
		em.persist(women4);
		em.persist(women5);
		
		em.getTransaction().commit();
		
		
	}
	
	
	
	private void loadColorInsideDB(EntityManager em)
	{
		em.getTransaction().begin();
		
		//Adding sizes.....
		Color black  = new Color();
				black.setHexCode("#000000");
				black.setName("Black");	
			
		Color blue  = new Color();
		blue.setHexCode("#00008B");
			blue.setName("Blue");
				
		Color darkRed  = new Color();
			darkRed.setHexCode("#8B0000");
			darkRed.setName("Dark Red");	
			
		
		em.persist(black);
		em.persist(blue);
		em.persist(darkRed);
//		
			
		em.getTransaction().commit();
	}
	
	
	private void loadSizeInsideDB(EntityManager em)
	{
		em.getTransaction().begin();
		
		Size size_XS  = new Size();
		size_XS.setSizeName("XS");
		
		//Adding sizes.....
		Size size_S  = new Size();
				size_S.setSizeName("S");	
			
			
		Size size_M  = new Size();
			size_M.setSizeName("M");
			
		Size size_L  = new Size();
			size_L.setSizeName("L");
			
		Size size_XL  = new Size();
			size_XL.setSizeName("XL");
			
		Size size_XXL  = new Size();
			size_XXL.setSizeName("XXL");
				
		
		em.persist(size_XS);
		em.persist(size_S);
		em.persist(size_M);
		em.persist(size_L);
		em.persist(size_XL);
		em.persist(size_XXL);
			
			
//		
			
			
		em.getTransaction().commit();
	}


	
	
	
	private void startHSQLDatabaseServer()
	{
		Server server = new Server();
        server.setAddress("localhost");
        server.setDatabaseName(0, "shopping");
        server.setDatabasePath(0, "file:WebContent/hsqldb/test");
        server.setPort(1234);
        server.setTrace(true);
        server.setLogWriter(new PrintWriter(System.out));
        server.start();
	}
}
